<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class MY_Model extends CI_Model
{

    public $tb_name;
    public $tb_primary;

    public function __construct($tb_name = '', $tb_primary = 'id')
    {
        parent::__construct();
        if (!$tb_name) {
            $name = strtolower(get_class($this));
            $this->tb_name = str_replace('_model', '', $name);
        } else {
            $this->tb_name = $tb_name;
        }
        $this->tb_primary = $tb_primary;
        $this->load->database();
    }

    private function build_condition(&$cond)
    {
        if (!$cond) {
            return false;
        }
        if (isset($cond['select'])) {
            $this->db->select($cond['select']);
            unset($cond['select']);
        }
        if (isset($cond['where'])) {
            $this->db->where($cond['where']);
            unset($cond['where']);
        }
        if (isset($cond['or_where'])) {
            $this->db->or_where($cond['or_where']);
            unset($cond['or_where']);
        }
        if (isset($cond['where_in'])) {
            foreach ($cond['where_in'] as $key => $value) {
                $value && $this->db->where_in($key, $value);
            }
            unset($cond['where_in']);
        }
        if (isset($cond['where_not_in'])) {
            foreach ($cond['where_not_in'] as $key => $value) {
                $value && $this->db->where_not_in($key, $value);
            }
            unset($cond['where_not_in']);
        }
        if (isset($cond['group_by'])) {
            $this->db->group_by($cond['group_by']);
            unset($cond['group_by']);
        }
        if (isset($cond['order_by'])) {
            if (is_array($cond['order_by'])) {
                foreach ($cond['order_by'] as $key => $value) {
                    $escape = null;
                    if (is_array($value) && count($value) == 2) {
                        $escape = $value[1];
                        $value = $value[0];
                    }
                    $this->db->order_by($key, $value, $escape);
                }
            } else {
                $this->db->order_by($cond['order_by']);
            }
            unset($cond['order_by']);
        }
        if (isset($cond['start']) || isset($cond['limit'])) {
            $cond['start'] = $cond['start'] ? $cond['start'] : 0;
            if (!isset($cond['limit'])) {
                $cond['limit'] = 1;
            }
            $this->db->limit($cond['limit'], $cond['start']);
            unset($cond['start'], $cond['limit']);
        }
        if ($cond) {
            if (is_numeric($cond) && $this->tb_primary) {
                $this->db->where($this->tb_primary, $cond);
            } else {
                $this->db->where($cond);
            }
        }
    }

    public function get_total($cond = array())
    {
        $this->build_condition($cond);
        $this->db->from($this->tb_name);
        return $this->db->count_all_results();
    }

    public function get_result($cond = array())
    {
        if (!isset($cond['order_by']) && $this->tb_primary) {
            // 增加查询数据库排序条件
            $this->db->order_by($this->tb_primary, 'desc');
        }
        // 增加查询where条件
        $this->build_condition($cond);
        return $this->db->get($this->tb_name)->result_array();
    }

    public function get_row($cond = array(), $field = null)
    {
        if (!isset($cond['order_by'])) {
            if ($this->tb_primary && isset($cond['start'])) {
                $this->db->order_by($this->tb_primary, 'desc');
            }
        }
        if (!isset($cond['start']) && !isset($cond['limit'])) {
            $this->db->limit(1);
        }
        if ($field) {
            $cond['select'] = $field;
        }
        $this->build_condition($cond);
        $return = $this->db->get($this->tb_name)->row_array();
        return ($field && !is_array($field)) ? $return[$field] : $return;
    }

    public function set($data, $cond = null, $unescape = null, $debug = false)
    {
        if (!$data) {
            return false;
        }
        $escape = true;
        if (is_array($unescape) && count($unescape) > 0) {
            foreach ($unescape as $key) {
                $this->db->set($key, $data[$key], false);
                unset($data[$key]);
            }
        } elseif ($unescape === true) {
            $escape = false;
        }
        foreach ($data as $key => $value) {
            $this->db->set($key, $value, $escape);
        }
        if (!$cond) {
            if ($debug) {
                $query = $this->db->get_compiled_insert($this->tb_name);
                var_dump($query);
                return false;
            } else {
                $query = $this->db->insert($this->tb_name);
            }
        } else {
            $this->build_condition($cond);
            if ($debug) {
                $query = $this->db->get_compiled_update($this->tb_name);
                var_dump($query);
                return false;
            } else {
                $query = $this->db->update($this->tb_name);
            }
        }
        return $query;
    }

    public function del($cond = null)
    {
        if (!$cond) {
            return false;
        }
        $this->build_condition($cond);
        return $this->db->delete($this->tb_name);
    }

    public function batch_insert($data)
    {
        if (!$data) {
            return false;
        }
        return $this->db->insert_batch($this->tb_name, $data);
    }

    public function batch_update($data, $byfiled = null, $unescape = false)
    {
        if (!$data) {
            return false;
        }
        if ($unescape) {
            $this->db->set_update_batch($data, $byfiled ? $byfiled : $this->tb_primary, false);
        }
        return $this->db->update_batch($this->tb_name, $unescape ? null : $data, $byfiled ? $byfiled : $this->tb_primary);
    }

}